home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / diverses / tctnt / newisr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-27  |  2.7 KB  |  73 lines

  1. /* NEWISR.C: Chaining to and Returning Values in Registers */
  2.  
  3. #include <dos.h>
  4. #include <stdio.h>
  5.  
  6. #define INT_NUMBER 0x21   // Trap Interrupt 21H (!)
  7.  
  8. // A user-defined type for use with getvect() & setvect()
  9. typedef void interrupt far (*intvect)(...);
  10.  
  11. intvect OldISR;          // For storing address of old vector
  12.  
  13. //---------------------------------------------------------------
  14. void interrupt NewISR(unsigned bp, unsigned di, unsigned si,
  15.                       unsigned ds, unsigned es, unsigned dx,
  16.                       unsigned cx, unsigned bx, unsigned ax,
  17.                       unsigned ip, unsigned cs, unsigned flags) {
  18.  
  19. // We know flags, cs, ip, cx... aren't used!
  20. #pragma warn -par
  21.  
  22.   // Insert your ISR Code Here...
  23.   // .
  24.   // .
  25.   // If (I_am_Handling_The_Interrupt)
  26.   // {
  27.   //    Do_Whatever_I_need_to_and();
  28.   //    return;
  29.   // }
  30.  
  31. /* The following Code indirectly chains to the Old Vector by:
  32.    1.  Putting the Address of the Old ISR on the Stack
  33.    2.  Restoring the Value of Registers Pushed on the Stack
  34.    3.  Executing a Far Return which translates into a jump to
  35.        the address on the Stack (i.e. the Old Vector's Address) */
  36.  
  37.   _BX  =   bx;           //Restore value of BX register
  38.   _CX  =   ax;           //Save value of AX in CX
  39.    ax  =   FP_SEG((void far *)OldISR);  //Place address of OldISR
  40.    bx  =   FP_OFF((void far *)OldISR);  // on the stack
  41.   _AX  =  _CX  ;         //Restore value of AX register
  42.   __emit__(0x5D);        //asm  POP BP -> restore BP
  43.   __emit__(0x5F);        //asm  POP DI -> restore DI
  44.   __emit__(0x5E);        //asm  POP SI -> restore SI
  45.   __emit__(0x1F);        //asm  POP DS -> restore DS
  46.   __emit__(0x07);        //asm  POP ES -> restore ES
  47.   __emit__(0x5A);        //asm  POP DX -> restore DX
  48.   __emit__(0x59);        //asm  POP CX -> restore CX
  49.   __emit__(0xCB);        //asm  RETF   -> indirect far jump
  50.                          // to OldISR
  51.  
  52. /* NOTE: Any code of the ISR beyond this point will not be executed.
  53.          The above does not *CALL* the old ISR but rather *JUMPS* to
  54.          it. When the OldISR executes its IRET, control will resume
  55.          at the original location prior to the INTERRUPTion!! */
  56. #pragma warn .par       // restore state of 'parms not used' warning
  57. }  // end of newISR()
  58.  
  59. //*******************************************************************
  60. int main(void) {
  61.   unsigned CountDown = 999;
  62.  
  63.   OldISR = (intvect) getvect(INT_NUMBER);
  64.   setvect(INT_NUMBER, (intvect)NewISR);
  65.  
  66.   while(CountDown--)
  67.     printf("This is the countdown:  [%03d]\r", CountDown);
  68.   printf("\nThis is the end of the countdown !\n");
  69.  
  70.   setvect(INT_NUMBER, OldISR);
  71.   return 0; 
  72. }  // end of main()
  73.